package com.knowvoyage.knowvoyageserver.controller;

import com.knowvoyage.knowvoyageserver.pojo.dto.AiChatDto;
import com.knowvoyage.knowvoyageserver.pojo.vo.Result;
import com.knowvoyage.knowvoyageserver.service.AiChatService;
import com.knowvoyage.knowvoyageserver.util.ChatClient;
import com.knowvoyage.knowvoyageserver.util.ChatRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Map;


@Tag(name = "ai交流类", description = "用于后端接收前端的消息，并传给模型端获得响应并返回给前端，同时将内容存储到数据库中")
@Slf4j
@RestController
@RequestMapping("/aichat")
@RequiredArgsConstructor
public class AIChatController {

    private final AiChatService aiChatService;

    @Operation(summary = "非流式读", description = "")
    @PostMapping("/ask")
    public Mono<String> ask(@RequestBody AiChatDto aiChatDto) throws IOException, InterruptedException {
        ChatClient chatClient = new ChatClient();
        ChatRequest chatRequest = new ChatRequest(aiChatDto, false);
        return chatClient.getChatMessage(chatRequest);
    }

    @Operation(summary = "流式读", description = "")
    @PostMapping(value =  "/ask/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> stream_ask(@RequestBody AiChatDto aiChatDto) {
        ChatClient chatClient = new ChatClient();
        ChatRequest chatRequest = new ChatRequest(aiChatDto, true);
        return chatClient.getChatMessageStream(chatRequest);
    }

    @Operation(summary = "加载", description = "将指定回话的历史记录加载到ai中，同时可以通过mode加载不同的ai预设，0为无预设，1为语音对话，2为解题，3为出题")
    @GetMapping(value =  "/load")
    public Mono<String> load(@RequestParam Long dialogId, @RequestParam Integer mode){
        return aiChatService.load(dialogId, mode);
    }

    @Operation(summary = "ocr", description = "前端发送图片，后端返回图片中的文本")
    @PostMapping(value = "/ocr", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<String> ocr(@RequestPart("file") FilePart filePart) {
        ChatClient chatClient = new ChatClient();
        System.out.println();
        Path tempFile = Paths.get(System.getProperty("user.dir") + "/src/main/resources/uploads/" + new Date().getTime() + filePart.filename());

        // 使用响应式链式操作
        return filePart.transferTo(tempFile)
            .then(Mono.defer(() -> chatClient.ocr(tempFile)))
            .doFinally(signal -> {
                try {
                    Files.deleteIfExists(tempFile); // 确保删除临时文件
                } catch (IOException e) {
                    log.error("Failed to delete temp file: {}", tempFile, e);
                }
            });
    }

    @Operation(summary = "任意非流式读", description = "只需要两个值：ask mode ")
    @PostMapping("/chat")
    public Mono<String> chat(@RequestBody Map<String, Object> item) {
        ChatClient chatClient = new ChatClient();
        return chatClient.chat(item);
    }

    @Operation(summary = "任意流式读", description = "只需要两个值：ask mode ")
    @PostMapping(value  ="/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> stream_chat(@RequestBody Map<String, Object> item) {
        ChatClient chatClient = new ChatClient();
        return chatClient.stream_chat(item);
    }

    @Operation(summary = "非流式ai出题", description = "需要值：subject difficulty ")
    @PostMapping(value = "/question")
    public Mono<Result<String>> question(@RequestBody Map<String, Object> item) {
        ChatClient chatClient = new ChatClient();
        return chatClient.question(item);
    }

}
